from django_redis import get_redis_connection
from rest_framework.views import APIView
from rest_framework.response import Response
from carts.serializers import CartsSerializers, CartSerializers, CartDeleteSerializers, CartSelectAllSerializers
import pickle, base64
from goods.models import SKU
# Create your views here.


class CartsView(APIView):
    def perform_authentication(self, request):
        # 先不进行用户是否存在的判断
        pass

    def post(self, request):

        data = request.data

        ser = CartsSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data.get('sku_id')
        count = ser.validated_data.get('count')
        selected = ser.validated_data.get('selected')

        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 保存在redis中
            conn = get_redis_connection('cart')
            conn.hincrby('cart_%s' % user.id, sku_id, count)
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)

        else:
            # 用户为登录保存在cookie中
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}

            sku = cart.get(sku_id)
            if sku:
                count += int(sku['count'])

            cart[sku_id] = {
                'count':count,
                'selected': selected
            }

            cart_cookie=base64.b64encode(pickle.dumps(cart)).decode()
            response = Response(ser.data)
            response.set_cookie('cart_cookie', cart_cookie, 60*60*24*7)

            return response

    def get(self, request):

        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 获取redis数据
            conn = get_redis_connection('cart')
            cart_count = conn.hgetall('cart_%s' % user.id)
            cart_selected = conn.smembers('cart_selected_%s'%user.id)

            # 构造数据
            cart = {}
            for sku_id, count in cart_count.items():
                cart[int(sku_id)]={
                    'count':int(count),
                    'selected':sku_id in cart_selected
                }

        else:
            # 用户为登录保存在cookie中
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}
        # sku_list=[]
        # for sku_id in cart.keys():
        #     sku = SKU.objects.get(id=sku_id)
        #     sku_list.append(sku)
        sku_list = SKU.objects.filter(id__in=cart.keys())
        for sku in sku_list:
            sku.count = cart[sku.id]['count']
            sku.selected=cart[sku.id]['selected']

        ser = CartSerializers(sku_list, many=True)

        return Response(ser.data)

    def put(self, request):

        data = request.data

        ser = CartsSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data.get('sku_id')
        count = ser.validated_data.get('count')
        selected = ser.validated_data.get('selected')

        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 保存在redis中
            conn = get_redis_connection('cart')
            cart_count = conn.hgetall('cart_%s' % user.id)
            for redis_sku_id, redis_count in cart_count.items():
                if count != int(redis_count):
                    new_count = count - int(redis_count)
                    conn.hincrby('cart_%s' % user.id, sku_id, new_count)
            if not selected:
                conn.srem('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)

        else:
            # 用户为登录保存在cookie中
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}

            cart[sku_id] = {
                'count': count,
                'selected': selected
            }

            cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
            response = Response(ser.data)
            response.set_cookie('cart_cookie', cart_cookie, 60 * 60 * 24 * 7)

            return response

    def delete(self, request):

        data = request.data

        ser = CartDeleteSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data.get('sku_id')

        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 保存在redis中
            conn = get_redis_connection('cart')
            conn.hdel('cart_%s' % user.id, sku_id)
            conn.srem('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)

        else:
            # 用户为登录保存在cookie中
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}
            cart.pop(sku_id)
            cart_cookie=base64.b64encode(pickle.dumps(cart)).decode()
            response = Response(ser.data)
            response.set_cookie('cart_cookie', cart_cookie, 60*60*24*7)

            return response


class CartsSelectAllView(APIView):
    def perform_authentication(self, request):
        # 先不进行用户是否存在的判断
        pass

    def put(self, request):
        data = request.data

        ser = CartSelectAllSerializers(data=data)
        ser.is_valid()
        selected = ser.validated_data.get('selected')

        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 保存在redis中
            conn = get_redis_connection('cart')
            cart_count = conn.hgetall('cart_%s' % user.id)
            for sku_id, redis_count in cart_count.items():
                if not selected:
                    conn.srem('cart_selected_%s' % user.id, sku_id)
                else:
                    conn.sadd('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)

        else:
            # 用户为登录保存在cookie中
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}
            for sku_id in cart.keys():
                sku = cart.get(sku_id)
                cart[sku_id] = {
                    'count': sku['count'],
                    'selected': selected
                }
            cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
            response = Response(ser.data)
            response.set_cookie('cart_cookie', cart_cookie, 60 * 60 * 24 * 7)

            return response


